﻿Imports System
Imports System.Reflection
Imports System.Workflow.ComponentModel
Imports System.Workflow.ComponentModel.Compiler
Imports System.Workflow.ComponentModel.Design

Namespace System.Workflow.Activities
    Friend NotInheritable Class InvokeWorkflowValidator
        Inherits ActivityValidator
        ' Methods
        Public Overrides Function Validate(ByVal manager As ValidationManager, ByVal obj As Object) As ValidationErrorCollection
            Dim handler As WalkerEventHandler = Nothing
            Dim validationErrors As ValidationErrorCollection = MyBase.Validate(manager, obj)
            Dim activity As InvokeWorkflowActivity = [TryCast](obj,InvokeWorkflowActivity)
            If (activity Is Nothing) Then
                Throw New ArgumentException(SR.GetString("Error_UnexpectedArgumentType", New Object() { GetType(InvokeWorkflowActivity).FullName }), "obj")
            End If
            If (activity.TargetWorkflow Is Nothing) Then
                Dim error As New ValidationError(SR.GetString("Error_TypePropertyInvalid", New Object() { "TargetWorkflow" }), &H116) { _
                    .PropertyName = "TargetWorkflow" _
                }
                validationErrors.Add([error])
                Return validationErrors
            End If
            Dim service As ITypeProvider = DirectCast(manager.GetService(GetType(ITypeProvider)), ITypeProvider)
            If (service Is Nothing) Then
                Throw New InvalidOperationException(SR.GetString("General_MissingService", New Object() { GetType(ITypeProvider).FullName }))
            End If
            Dim targetWorkflow As Type = activity.TargetWorkflow
            If ((targetWorkflow.Assembly Is Nothing) AndAlso (Not service.LocalAssembly Is Nothing)) Then
                Dim type As Type = service.LocalAssembly.GetType(targetWorkflow.FullName)
                If (Not type Is Nothing) Then
                    targetWorkflow = type
                End If
            End If
            If Not TypeProvider.IsAssignable(GetType(Activity), targetWorkflow) Then
                Dim error2 As New ValidationError(SR.GetString("Error_TypeIsNotRootActivity", New Object() { "TargetWorkflow" }), &H60E) { _
                    .PropertyName = "TargetWorkflow" _
                }
                validationErrors.Add(error2)
                Return validationErrors
            End If
            Dim seedActivity As Activity = Nothing
            Try 
                seedActivity = [TryCast](Activator.CreateInstance(targetWorkflow),Activity)
            Catch exception1 As Exception
            End Try
            If (seedActivity Is Nothing) Then
                Dim error3 As New ValidationError(SR.GetString("Error_GetCalleeWorkflow", New Object() { activity.TargetWorkflow }), &H500) { _
                    .PropertyName = "TargetWorkflow" _
                }
                validationErrors.Add(error3)
                Return validationErrors
            End If
            Dim walker As New Walker
            If (handler Is Nothing) Then
                handler = Function (ByVal w As Walker, ByVal args As WalkerEventArgs) 
                    If (TypeOf args.CurrentActivity Is WebServiceInputActivity AndAlso DirectCast(args.CurrentActivity, WebServiceInputActivity).IsActivating) Then
                        Dim item As New ValidationError(SR.GetString("Error_ExecWithActivationReceive"), &H614) { _
                            .PropertyName = "Name" _
                        }
                        validationErrors.Add(item)
                        args.Action = WalkerAction.Abort
                    End If
                End Function
            End If
            AddHandler walker.FoundActivity, handler
            walker.Walk(seedActivity)
            Dim flag As Boolean = False
            Dim activity3 As Activity = activity.Parent
            Do While (Not activity3 Is Nothing)
                If (TypeOf activity3 Is CompensatableTransactionScopeActivity OrElse TypeOf activity3 Is TransactionScopeActivity) Then
                    flag = True
                    Exit Do
                End If
                activity3 = activity3.Parent
            Loop
            If flag Then
                Dim error4 As New ValidationError(SR.GetString("Error_ExecInAtomicScope"), &H502)
                validationErrors.Add(error4)
            End If
            Dim binding As WorkflowParameterBinding
            For Each binding In activity.ParameterBindings
                Dim property As PropertyInfo = Nothing
                [property] = targetWorkflow.GetProperty(binding.ParameterName)
                If ([property] Is Nothing) Then
                    Dim error5 As New ValidationError(SR.GetString("Error_ParameterNotFound", New Object() { binding.ParameterName }), &H504)
                    If InvokeWorkflowActivity.ReservedParameterNames.Contains(binding.ParameterName) Then
                        error5.PropertyName = ParameterInfoBasedPropertyDescriptor.GetParameterPropertyName(activity.GetType, binding.ParameterName)
                    End If
                    validationErrors.Add(error5)
                    [Continue] For
                End If
                Dim propertyType As Type = [property].PropertyType
                If (Not binding.GetBinding(WorkflowParameterBinding.ValueProperty) Is Nothing) Then
                    Dim errors As ValidationErrorCollection = ValidationHelpers.ValidateProperty(manager, activity, binding.GetBinding(WorkflowParameterBinding.ValueProperty), New PropertyValidationContext(binding, Nothing, binding.ParameterName), New BindValidationContext(propertyType, AccessTypes.Read))
                    If (errors.Count <> 0) Then
                        validationErrors.AddRange(errors)
                    End If
                End If
            Next
            Return validationErrors
        End Function

    End Class
End Namespace

